﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using LevelData;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace GGJ11
{
    class LayerGameObject
    {
        private Level level;
        private Animation door;
        private Animation doorClose;
        private Animation pass1;
        private Animation passClose1;
        private Animation pass2;
        private Animation passClose2;
        private Animation pass3;
        private Animation passClose3;
        private Animation openDoor;
        private Animation handleExit;
        private Animation handle1;
        private Animation handle2;
        private Animation handle3;
        private Animation handle1Idle;
        private Animation handle2Idle;
        private Animation handle3Idle;
        private Animation money;
        private Animation gold;
        private Animation poison;
        private Animation poisonPlus;
        private Animation star;


        public LayerGameObject(ContentManager content)
        {
            level = content.ServiceProvider.GetService(typeof(Level)) as Level;
            door = new Animation(content.Load<Texture2D>("Sprites/door"), 0.35f, false);
            doorClose = new Animation(content.Load<Texture2D>("Sprites/doorClose"), 0.1f, false);
            pass1 = new Animation(content.Load<Texture2D>("Sprites/pass1"), 0.35f, false);
            passClose1 = new Animation(content.Load<Texture2D>("Sprites/passClose1"), 0.1f, false);
            pass2 = new Animation(content.Load<Texture2D>("Sprites/pass2"), 0.35f, false);
            passClose2 = new Animation(content.Load<Texture2D>("Sprites/passClose2"), 0.1f, false);
            pass3 = new Animation(content.Load<Texture2D>("Sprites/pass3"), 0.35f, false);
            passClose3 = new Animation(content.Load<Texture2D>("Sprites/passClose3"), 0.1f, false);
            openDoor = new Animation(content.Load<Texture2D>("Sprites/Player/Die"), 0.1f, false);

            handleExit = new Animation(content.Load<Texture2D>("Sprites/handleExit"), 0.1f, false);
            handle1 = new Animation(content.Load<Texture2D>("Sprites/handle1"), 0.1f, false);
            handle2 = new Animation(content.Load<Texture2D>("Sprites/handle2"), 0.1f, false);
            handle3 = new Animation(content.Load<Texture2D>("Sprites/handle3"), 0.1f, false);
            handle1Idle = new Animation(content.Load<Texture2D>("Sprites/handle1Idle"), 0.1f, false);
            handle2Idle = new Animation(content.Load<Texture2D>("Sprites/handle2Idle"), 0.1f, false);
            handle3Idle = new Animation(content.Load<Texture2D>("Sprites/handle3Idle"), 0.1f, false);

            money = new Animation(content.Load<Texture2D>("Sprites/GoldStatic"), 0.1f, true);
            gold = new Animation(content.Load<Texture2D>("Sprites/money"), 0.1f, true);
            poison = new Animation(content.Load<Texture2D>("Sprites/poison"), 0.08f, true);
            poisonPlus = new Animation(content.Load<Texture2D>("Sprites/poisonplus"), 0.1f, false);
            star = new Animation(content.Load<Texture2D>("Sprites/star"), 0.1f, false);

            Initialize();
        }

        public void Initialize()
        {

            for (int i = 0; i < level.ObjectList.Count; i++)
            {
                switch (level.ObjectList[i].type)
                {
                    case ObjectType.Gold:
                        level.ObjectList[i].sprite.PlayAnimation(gold);
                        break;
                    case ObjectType.Money:
                        level.ObjectList[i].sprite.PlayAnimation(money);
                        break;
                    case ObjectType.PoisonHealt:
                        level.ObjectList[i].sprite.PlayAnimation(poison);
                        break;
                    case ObjectType.PoisonHealtPlus:
                        level.ObjectList[i].sprite.PlayAnimation(poisonPlus);
                        break;
                    case ObjectType.Star:
                        level.ObjectList[i].sprite.PlayAnimation(star);
                        break;
                    case ObjectType.DoorA:
                        level.ObjectList[i].sprite.PlayAnimation(passClose1);
                        level.ObjectList[i].typeDoor = 0;
                        break;
                    case ObjectType.OpenDoorA:
                        level.ObjectList[i].sprite.PlayAnimation(handle1Idle);
                        level.ObjectList[i].typeDoor = 0;
                        break;
                    case ObjectType.DoorB:
                        level.ObjectList[i].sprite.PlayAnimation(passClose2);
                        level.ObjectList[i].typeDoor = 1;
                        break;
                    case ObjectType.OpenDoorB:
                        level.ObjectList[i].sprite.PlayAnimation(handle2Idle);
                        level.ObjectList[i].typeDoor = 1;
                        break;
                    case ObjectType.DoorC:
                        level.ObjectList[i].sprite.PlayAnimation(passClose3);
                        level.ObjectList[i].typeDoor = 2;
                        break;
                    case ObjectType.OpenDoorC:
                        level.ObjectList[i].sprite.PlayAnimation(handle3Idle);
                        level.ObjectList[i].typeDoor = 2;
                        break;
                    case ObjectType.Exit:
                        level.ObjectList[i].sprite.PlayAnimation(doorClose);
                        level.ObjectList[i].typeDoor = 3;
                        break;
                    case ObjectType.openExit:
                        level.ObjectList[i].sprite.PlayAnimation(handleExit);
                        level.ObjectList[i].typeDoor = 3;
                        break;
                    case ObjectType.CheckPoint:
                        level.ObjectList[i].sprite.PlayAnimation(poisonPlus);
                        //level.ObjectList[i].typeDoor = 3;
                        break;
                }

            }
        }

        //chec if player collide with money
        public void Update(GameTime gameTime)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

            for(int  i= 0; i < level.ObjectList.Count; i++)
            {
                if (level.ObjectList[i].BoundingRectangle.Intersects(level.playerLevel.BoundingRectangle))
                {
                    switch (level.ObjectList[i].type)
                    {
                        case ObjectType.Gold:
                            OnMoneyCollected(level.ObjectList[i], level.playerLevel);
                            level.soundList.Add(SoundType.dollar);
                            break;
                        case ObjectType.Money:
                            OnMoneyCollected(level.ObjectList[i], level.playerLevel);
                            level.soundList.Add(SoundType.dollar);
                            break;
                        case ObjectType.PoisonHealt:
                            OnHealthCollected(level.ObjectList[i], level.playerLevel);
                            level.soundList.Add(SoundType.poison);
                            break;
                        case ObjectType.Star:
                            OnStarCollected(level.ObjectList[i], level.playerLevel);
                            level.soundList.Add(SoundType.star);
                            break;
                        case ObjectType.PoisonHealtPlus:
                            OnLifeCollected(level.ObjectList[i], level.playerLevel);
                            level.soundList.Add(SoundType.poison);
                            break;
                        case ObjectType.OpenDoorA:
                            OnOpenDoor(level.ObjectList[i]);
                            break;
                        case ObjectType.OpenDoorB:
                            OnOpenDoor(level.ObjectList[i]);
                            break;
                        case ObjectType.OpenDoorC:
                            OnOpenDoor(level.ObjectList[i]);
                            break;
                        case ObjectType.openExit:
                            OnOpenDoor(level.ObjectList[i]);
                            break;
                        case ObjectType.CheckPoint:
                            CheckPoint(level.ObjectList[i]);
                            break;
                        case ObjectType.Exit:
                            //check if player arrive at the end of the level
                                if (level.playerLevel.isOnGround && level.ObjectList[i].open)
                                {
                                    level.playerLevel.position.X = level.ObjectList[i].position.X;
                                    level.playerLevel.onExit = true;
                                    level.soundList.Add(SoundType.nextLevel);
                                }
                            break;
                    }
                }
            }
        }

        private void CheckPoint(ObjGame objGame)
        {
            level.playerLevel.start = objGame.position - (Vector2.UnitY*Tile.Height);
        }

        private void OnOpenDoor(ObjGame objGame)
        {
            for (int i = 0; i < level.ObjectList.Count; i++)
            {
                //add sprite push button
                if (level.ObjectList[i].typeDoor == objGame.typeDoor && !level.ObjectList[i].open)
                {

                    if (level.ObjectList[i].type == ObjectType.DoorA || level.ObjectList[i].type == ObjectType.DoorB ||
                        level.ObjectList[i].type == ObjectType.DoorC || level.ObjectList[i].type == ObjectType.Exit)
                    {
                        level.soundList.Add(SoundType.openDoor);
                        objGame.open = true;

                        switch (level.ObjectList[i].type)
                        {
                            case ObjectType.DoorA:
                                objGame.sprite.PlayAnimation(handle1);
                                level.ObjectList[i].sprite.PlayAnimation(pass1);
                                break;

                            case ObjectType.DoorB:
                                objGame.sprite.PlayAnimation(handle2);
                                level.ObjectList[i].sprite.PlayAnimation(pass2);
                                break;

                            case ObjectType.DoorC:
                                objGame.sprite.PlayAnimation(handle3);
                                level.ObjectList[i].sprite.PlayAnimation(pass3);
                                break;

                            case ObjectType.Exit:
                                level.ObjectList[i].sprite.PlayAnimation(door);
                                break;
                        }
                        level.SetCollision(level.ObjectList[i].posX, level.ObjectList[i].posY);
                        level.ObjectList[i].open = true;
                        level.soundList.Add(SoundType.door);
                    }
                }
            }
        }

        //remove money from list if there is a collision
        private void OnMoneyCollected(ObjGame money, player player)
        {
            player.points += (int)money.type;
            level.ObjectList.Remove(money);
        }

        private void OnHealthCollected(ObjGame poison, player player)
        {
            player.health++;
            level.ObjectList.Remove(poison);
        }

        private void OnLifeCollected(ObjGame poison, player player)
        {
            player.life++;
            level.ObjectList.Remove(poison);
        }

        private void OnStarCollected(ObjGame star, player player)
        {
            player.invulnerability = player.timeInvulnerability;
            level.ObjectList.Remove(star);
        }

        //update the service whrn load the next level
        public void UpdateLevelService(ContentManager content)
        {
            level = content.ServiceProvider.GetService(typeof(Level)) as Level;
            Initialize();
        }

    }
}
